import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.tree import DecisionTreeClassifier

# 加载数据集
breast_cancer = load_breast_cancer()
features, labels = breast_cancer.data, breast_cancer.target
# 划分训练集和测试集
features_train, features_test, labels_train, labels_test = train_test_split(features, labels, test_size=0.2,
                                                                            random_state=42)
# 定义决策树和 GradientBoost 分类器
decision_tree_classifier = DecisionTreeClassifier(random_state=0)
gradient_boost_classifier = GradientBoostingClassifier(random_state=0, n_estimators=100, learning_rate=0.1)
decision_tree_classifier.fit(features_train, labels_train)
gradient_boost_classifier.fit(features_train, labels_train)
score_decision_tree = decision_tree_classifier.score(features_test, labels_test)
score_gradient_boost = gradient_boost_classifier.score(features_test, labels_test)
print("---预测准确率---")
print("决策树: ", score_decision_tree)
print("Gradient: ", score_gradient_boost)

# 交叉验证评估分类器性能
decision_tree_scores = []
gradient_boost_scores = []
for i in range(10):
    decision_tree_score = cross_val_score(DecisionTreeClassifier(), features, labels, cv=10).mean()
    decision_tree_scores.append(decision_tree_score)
    gradient_boost_score = cross_val_score(GradientBoostingClassifier(n_estimators=25, learning_rate=0.1), features,
                                           labels, cv=10).mean()
    gradient_boost_scores.append(gradient_boost_score)

plt.figure()
plt.title('Gradient Boost VS Decision Tree')
plt.xlabel('Index')
plt.ylabel('Accuracy')
plt.plot(range(10), decision_tree_scores, label='Decision Tree')
plt.plot(range(10), gradient_boost_scores, label='Gradient Boost')
plt.legend()
plt.show()

# 观察学习率对分类准确度的影响
gradient_boost_scores = []
learning_rates = [0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85,
                  0.9, 0.95]
for lr in learning_rates:
    gradient_boost_classifier = GradientBoostingClassifier(learning_rate=lr)
    gradient_boost_score = cross_val_score(gradient_boost_classifier, features, labels, cv=10).mean()
    gradient_boost_scores.append(gradient_boost_score)

plt.figure()
plt.title('Gradient Boost: Impact of Learning Rate')
plt.xlabel('Learning Rate')
plt.ylabel('Accuracy')
plt.plot(learning_rates, gradient_boost_scores)
plt.show()

# 观察弱分类器数量对分类准确度的影响
gradient_boost_scores = []
for i in range(1, 50):
    gradient_boost_classifier = GradientBoostingClassifier(n_estimators=i)
    gradient_boost_score = cross_val_score(gradient_boost_classifier, features, labels, cv=10).mean()
    gradient_boost_scores.append(gradient_boost_score)

plt.figure()
plt.title('Gradient Boost: Impact of Weak Learners')
plt.xlabel('n_estimators')
plt.ylabel('Accuracy')
plt.plot(range(1, 50), gradient_boost_scores)
plt.show()
